﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Reflection;
using System.Linq.Expressions;

namespace System.Data.Entity
{
    public static class EntityTypeConfigurationExtensions
    {
        public static void ToStructure<TEntityType>(this EntityTypeConfiguration<TEntityType> entity, string namingFormat, params object[] args)
            where TEntityType : class
        {
            string tableName = string.Format(namingFormat, args);
            entity.ToTable(tableName);
        }

        public static EntityTypeConfiguration<TEntityType> Describe<TEntityType>(this EntityTypeConfiguration<TEntityType> entity, Action<EntityTypeConfiguration<TEntityType>> description)
            where TEntityType : class
        {
            description(entity);
            return entity;
        }

        public static void HasForeignKey<TEntityType, TTargetEntity>(this EntityTypeConfiguration<TEntityType> entity, Expression<Func<TEntityType, TTargetEntity>> fkProperty, bool willCascadeOnDelete)
            where TEntityType : class
            where TTargetEntity : class
        {
            // http://stackoverflow.com/questions/671968/retrieving-property-name-from-lambda-expression
            var expression = (fkProperty.Body as MemberExpression);
            if (expression == null) throw new InvalidExpressionException("Expression is not a property");
            string name = expression.Member.Name;
            String fkColumnName = String.Format("{0}ID", name);

            entity.HasRequired<TTargetEntity>(fkProperty).WithMany().MapColumns(fkColumnName).WillCascadeOnDelete(willCascadeOnDelete);
        }
    }

    public static class ComplexTypeConfigurationExtensions
    {
        public static ComplexTypeConfiguration<TEntityType> Describe<TEntityType>(this ComplexTypeConfiguration<TEntityType> entity, Action<ComplexTypeConfiguration<TEntityType>> description)
           where TEntityType : class
        {
            description(entity);
            return entity;
        }     
    }

    
}
